"""
Handles the import of modules needed by Symbide.

Modules should be only imported when really needed and as late as possible. This
makes the startup faster and the memory usage smaller.
To load a module that possible gives an error while loading (e.g it's not 
available) use:

from Symbide import ModuleManager
if ModuleManager.hasModule("module"):
    import module
"""

MODULES = {}

ALL_MODULES = (
               'gtk',
               'gtksourceview',
               'src.extensions.mathml.mathdom.mathdom', #on windows this gives me trouble
               'numpy',
               'sympy',
               'Ft',
               'PIL',
               'pylab',
               'Gnuplot',
               'ctypes',
               )

class ModuleManager:
    """
    Handles the import of modules needed by Symbide.
    """
    def loadModule(self, module):
        """
        Tries to load the given module and adds it as key to MODULES with either
        True if it is loadable or False if it is not as item.
        """
        assert isinstance(module, str)
        try:
            exec 'import %s'%module
            MODULES[module] = True
            return True
        except:
            MODULES[module] = False
            return False
        
    def hasModule(self, module):
        """
        Returns True if the module is loadable and False if it is not.
        """
        assert isinstance(module, str)
        if MODULES.has_key(module):
            return MODULES[module]
        else:
            return self.loadModule(module)
        
    def getModules(self):
        """
        Returns a list of all modules with additional status information. Status
        information can be:
            True, if it is successfull loaded
            False, if it wasn't able to load the module
            None, if it wasn't yet tried to load this module
        The list has the following format: [(module1, status), ..].
        """
        modules = MODULES.items()
        modulenames = MODULES.keys()
        for m in ALL_MODULES:
            if not m in modulenames:
                modules.append((m, None))
        modules.sort(key=lambda x:x[0])
        return modules
